/**
 * 
 */
package com.ihome.framework.core.event.group;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;

import com.ihome.framework.core.event.IHomeEventBusHandler.EventBusWorkHandler;
import com.ihome.framework.core.event.IHomeEventBusHandler.EventDto;
import com.lmax.disruptor.dsl.EventHandlerGroup;

/**
 * @author zww
 *
 */
public class EventBusHandlerGroup<E extends EventDto> implements IHomeEventBusGroupRegister<E>{


    private EventHandlerGroup<E> INSTANCE;
    
    protected transient ApplicationContext applicationContext;


    public EventBusHandlerGroup(EventHandlerGroup<E> group,ApplicationContext applicationContext) {
        this.INSTANCE = group;
        this.applicationContext = applicationContext;
    }

    /* (non-Javadoc)
     * @see com.ihome.framework.core.event.group.IEventBusHandlerGroup#thenHandlerGroupDone(com.ihome.framework.core.event.IHomeEventBusHandler.EventBusHandler[])
     */
    @Override
    public IHomeEventBusGroupRegister<E> thenGroupDoneWith(EventBusWorkHandler<E>... handlers) {
        return new EventBusHandlerGroup<E>(INSTANCE.then(handlers),this.applicationContext);
    }
    
    /* (non-Javadoc)
     * @see com.ihome.framework.core.event.group.IEventBusHandlerGroup#thenGroupDoneWithPool(com.ihome.framework.core.event.IHomeEventBusHandler.EventBusWorkHandler[])
     */
    @Override
    public IHomeEventBusGroupRegister<E> thenGroupDoneWithPool(EventBusWorkHandler<E>... handlers) {
        return new EventBusHandlerGroup<E>(INSTANCE.thenHandleEventsWithWorkerPool(handlers),this.applicationContext);
    }
    
    /* (non-Javadoc)
     * @see com.ihome.framework.core.event.group.IEventBusHandlerGroup#handleEventsWithPool(com.ihome.framework.core.event.IHomeEventBusHandler.EventBusWorkHandler[])
     */
    @Override
    public IHomeEventBusGroupRegister<E> handleEventsWithPool(EventBusWorkHandler<E>... handlers) {
        return new EventBusHandlerGroup<E>(INSTANCE.handleEventsWithWorkerPool(handlers),this.applicationContext);
    }
    
    /* (non-Javadoc)
     * @see com.ihome.framework.core.event.group.IHomeEventGroupConsumer#handleEventsWith(com.ihome.framework.core.event.IHomeEventBusHandler.EventBusHandler[])
     */
    @Override
    public IHomeEventBusGroupRegister<E> handleEventsWith(EventBusWorkHandler<E>... handlers) {
        return new EventBusHandlerGroup<E>(INSTANCE.handleEventsWith(handlers),this.applicationContext);
    }

    /* (non-Javadoc)
     * @see com.ihome.framework.core.event.group.IHomeEventBusGroupRegister#thenGroupDoneWithPool(java.lang.Class, java.lang.Integer)
     */
    @Override
    public IHomeEventBusGroupRegister<E> thenGroupDoneWithPool(Class<? extends EventBusWorkHandler<E>> clz, Integer consumerSize) {
        return thenGroupDoneWithPool(createWorkHandler(clz, consumerSize));
    }
    
    
    public EventBusWorkHandler[] createWorkHandler(Class<? extends EventBusWorkHandler<E>> clz, Integer consumerSize){
        List<EventBusWorkHandler<E>> handlers = new ArrayList<EventBusWorkHandler<E>>();
        for (int i = 0; i < consumerSize; i++) {
            EventBusWorkHandler<E> handler = applicationContext.getBean(clz);
            if(i != 0){
                // check
                Assert.isTrue(handlers.get(i-1) != handler,"work handler with consumer @Scope(value='prototype')");
            }
            handlers.add(handler);
        }
        return handlers.toArray(new EventBusWorkHandler[]{});
    }
    

    /* (non-Javadoc)
     * @see com.ihome.framework.core.event.group.IHomeEventBusRegister#handleEventsWithPool(java.lang.Class, java.lang.Integer)
     */
    @Override
    public IHomeEventBusGroupRegister<E> handleEventsWithPool(Class<? extends EventBusWorkHandler<E>> clz, Integer consumerSize) {
        return handleEventsWithPool(createWorkHandler(clz, consumerSize));
    }

}
